#include "ActionFlee.h"
#include "Steering.h"
#include "World.h"
#include "Hostility.h"

ActionFlee::ActionFlee()
{
	Memory::meminfo_t fake ;
	fake.timeSinceSeen = 100000 ;
	e_target__ = std::pair<Entity*,Memory::meminfo_t>(0,fake) ;
	timeToFlee__ = 0 ;
	timeToSend__ = 0 ;
	executer__=0;
}

ActionFlee::ActionFlee(vector3df target)
{
	Memory::meminfo_t fake ;
	fake.timeSinceSeen = 100000 ;
	e_target__ = std::pair<Entity*,Memory::meminfo_t>(0,fake) ;
	v_target__ = target;
	timeToFlee__ = 0 ;
	timeToSend__ = 0 ;
	executer__=0;
}

ActionFlee::~ActionFlee()
{
}

bool ActionFlee::execute(Entity* executer)
{
	executer__ = executer ;
   	timeToSend__ += World::getWorld()->elapsedTime();
	timeToFlee__ += World::getWorld()->elapsedTime() ;
	
	NPCEntity * realExecuter = dynamic_cast<NPCEntity *>(executer) ;
	e_target__ = realExecuter->getMemory()->getNearestEnemyPair(executer) ;

	// we do not want to flee null entities or dead ones
	if((e_target__.first != 0) /*|| ((dynamic_cast<LivingEntity*>(e_target__))->isAlive())*/)
	{
		float safeDist = e_target__.first->getNode()->getPosition().getDistanceFrom(executer->getNode()->getPosition()) ;
		if((safeDist < 400) || (timeToFlee__ < 1.5))
		{
            if(timeToSend__ >= 2)
            {        
    			// sending messages to all allies
    			std::map<Entity*, Memory::meminfo_t> allies = realExecuter->getMemory()->getMemoryByHostility(Hostility::ALLIED) ;
    			std::map<Entity*,Memory::meminfo_t>::iterator it = allies.begin();
    			while(it != allies.end())
    			{
    				std::pair<Entity*,Memory::meminfo_t> currentMemory = *it ;
    				std::string type = e_target__.first->getType().c_str();
    				realExecuter->sendMessage(currentMemory.first,"Under_Attack",type); 
    				//std::cout << "envoi de messages aux allies " << std::endl;
    				it++;
    			}
    			
    			timeToSend__ = 0 ;
            }

			Steering::Flee(realExecuter,e_target__.second.position) ;
			return false ;
		}
		else
		{
			realExecuter->getMemory()->timeToForget(e_target__.first) ;
			return true ;
		}
	}
	else
	{
		return true ;
	}

	if(debug[Debug::PLAN_INFO])
	{
		std::cout << "fleeing" << std::endl ;
	}

}

bool ActionFlee::checkConditions()
{
	if(executer__ != 0)
	{
		NPCEntity * realExecuter = dynamic_cast<NPCEntity *>(executer__) ;
	
		if(realExecuter->getMemory()->isEmptyMemory(realExecuter->getMemory()->getNearestEnemyPair(realExecuter)))
		{
			return false ;
		}
	}


     return true ;
}
 
